/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ParTreeVisualizer;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;

/**
 *
 * @author mwh
 */
public class BilingualPanel extends JPanel implements Printable {

    List<String> s1words;

    List<String> s2words;

    List<WordAlignement> alignements;

    private int spacing = 5;

    private int xpos = 50;

    private int ypos1 = 50;

    private int yDelta = 100;

    private int ypos2 = ypos1 + yDelta;

    //  Font f = new Font("Serif", Font.ROMAN_BASELINE, 14);
    Font f = new Font("Times New Roman", Font.PLAIN, 18);


    public BilingualPanel(SentenceAlignement sa) {

        s1words = sa.s1;
        s2words = sa.s2;
        alignements = sa.a;


        setBackground(Color.WHITE);

    }


    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        drawPage(g2);
    }


    public void drawPage(Graphics2D g2) {

        // Arrays for holding the posistion of all the words.
        // The posistion saved is the center of the word.
        List<Integer> l1pos = new ArrayList<Integer>();
        List<Integer> l2pos = new ArrayList<Integer>();

        g2.setFont(f);
        drawSentences(g2, l1pos, l2pos, g2.getFontMetrics());
        drawAlignments(g2, l1pos, l2pos, g2.getFontMetrics());
    }


    public void drawSentences(Graphics2D g2, List<Integer> s1WordsXPos, List<Integer> s2WordsXPos, FontMetrics fm) {



        // Find the collected width of all the words in sentence 1.
        Integer s1WordsWidth = 0;
        for (String w : s1words) {
            s1WordsWidth = s1WordsWidth + fm.stringWidth(w);
        }

        // Find the width of sentence one with spacing
        int s1Width = s1WordsWidth + (s1words.size() - 1) * spacing;

        // Find the collected width of all the words in sentence 1.
        Integer s2WordsWidth = 0;
        for (String w : s2words) {

            s2WordsWidth = s2WordsWidth + fm.stringWidth(w);
        }

        // Find the width of sentence one with spacing
        int s2Width = s2WordsWidth + (s2words.size() - 1) * spacing;

        // Find the widest sentence.
        int maxWidth = Math.max(s1Width, s2Width);

        // Set flag for which sentence is widest;
        boolean s1Widest = false;
        if (maxWidth == s1Width) {
            //     System.err.println("s1wide");
            s1Widest = true;
        }


        // Find the spacing for the most narrow sentence
        int spacing1 = spacing;
        int spacing2 = spacing;
        if (s1Widest) {
            spacing2 = (maxWidth - s2WordsWidth) / (s2words.size() - 1);
        } else {
            spacing1 = (maxWidth - s1WordsWidth) / (s1words.size() - 1);

        }


        int x = xpos;
        for (String w : s1words) {
            g2.drawString(w, x, ypos1);
            s1WordsXPos.add(x + ((int) fm.stringWidth(w) / 2));
            x = x + spacing1 + fm.stringWidth(w);
        }


        x = xpos;
        for (String w : s2words) {
            g2.drawString(w, x, ypos2);
            s2WordsXPos.add(x + ((int) fm.stringWidth(w) / 2));
            x = x + spacing2 + fm.stringWidth(w);
        }
    //  System.err.println(s1WordsXPos);
    //  System.err.println(s2WordsXPos);

    }


    public void drawAlignments(Graphics2D g2, List<Integer> s1WordsXPos, List<Integer> s2WordsXPos, FontMetrics fm) {
        int y2posAlign = ypos2 - fm.getHeight() + 4;

        for (WordAlignement a : alignements) {
            int x1;
            int y1;
            int x2;
            int y2;


            if (a.w1.size() == 1) {
                // If there is only one word one this side of the alignemt the 1-position is
                // just below the center of this word.
                Integer wp = (Integer) a.w1.toArray()[0];
                x1 = s1WordsXPos.get(wp);
                y1 = ypos1 + 4;
            } else {
                // Otherwisw find x-middle of aligned words;
                int xmin = Integer.MAX_VALUE;
                int xmax = Integer.MIN_VALUE;
                for (Integer wp : a.w1) {
                    //      System.err.println(s1WordsXPos.get(wp));
                    xmin = Math.min(xmin, s1WordsXPos.get(wp));
                    xmax = Math.max(xmax, s1WordsXPos.get(wp));
                }

                int centerX = (xmin + xmax) / 2;
//           System.err.println("center: " + centerX);

                // And the y-position be a third of the way down to the other sentence
                int centerY = ypos1 + ((y2posAlign - ypos1) / 3);

                x1 = centerX;
                y1 = centerY;


            }
            if (a.w2.size() == 1) {
                // If there is only one word one this side of the alignemt the 1-position is
                // just above the center of this word.
                Integer wp = (Integer) a.w2.toArray()[0];
                x2 = s2WordsXPos.get(wp);
                y2 = y2posAlign;
            } else {
                // Find x-middle of aligned words;
                int xmin = Integer.MAX_VALUE;
                int xmax = Integer.MIN_VALUE;
                for (Integer wp : a.w2) {
                    //            System.err.println(s2WordsXPos.get(wp));
                    xmin = Math.min(xmin, s2WordsXPos.get(wp));
                    xmax = Math.max(xmax, s2WordsXPos.get(wp));
                }

                int centerX = (xmin + xmax) / 2;
//                System.err.println("max " + xmax + "  min " + xmin);
//                System.err.println("center: " + centerX);

                // And let the y-position be a third of the way up to the other sentence.
                int centerY = y2posAlign - ((y2posAlign - ypos1) / 3);

                x2 = centerX;
                y2 = centerY;
            }

            if (a.w1.size() > 1) {
                // 'Draw' the x1-position towards the x2-position
                x1 = (2 * x1 + x2) / 3;

                // Draw lines from aligned words on this side to (x1,y1)
                for (Integer wp : a.w1) {
                    int wx = s1WordsXPos.get(wp);
                    g2.drawLine(wx, ypos1 + 4, x1, y1);
                }
            }

            if (a.w2.size() > 1) {
                // 'Draw' the x2-position towards the x2-position
                x2 = (x1 + 2 * x2) / 3;

                // Draw lines from aligned words on this side to (x2,y2)
                for (Integer wp : a.w2) {
                    int wx = s2WordsXPos.get(wp);
                    g2.drawLine(wx, y2posAlign, x2, y2);
                }
            }

            // Draw lines between aligned words or word-groups.
            g2.drawLine(x1, y1, x2, y2);
        }


    }


    public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
        if (page >= 1) {
            return NO_SUCH_PAGE;
        }
        Graphics2D g2 = (Graphics2D) g;
        g2.translate(pf.getImageableX(), pf.getImageableY());
        g2.scale(0.7, 0.7);
        drawPage(g2);


        return PAGE_EXISTS;
    }
}
